// Copyright 2012 Jay Young. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview
 *
 * Provides a visitor class that extracts @fileoverview information.
 */

var Token = com.google.javascript.rhino.Token;

/**
 * A node visitor that extracts @fileoverview information.  If a JSDoc block
 * at the head of a file does not have a @fileoverview annotation, then other
 * annotations (@author, @see, etc) will be attributed to the next node, which
 * is usually incorrect.  Always supply a @fileoverview tag!
 *
 * @constructor
 * @implements {Documenter.Visitor}
 */
var FileOverviewV = exports.FileOverviewV = function() {
  /**
   * The next visitor in the chain.
   *
   * @type {Documenter.Visitor}
   * @private
   */
  this.nextVisitor_ = null;
};


/**
 * @param {Documenter.Visitor} visitor The next visitor in the chain.
 */
FileOverviewV.prototype.setNext = function(visitor) {
  this.nextVisitor_ = visitor;
};


/**
 * Determine if a node contains @fileoverview information, extract it, and set
 * it on the DocInfo object.
 *
 * @param {Node} node The node to visit.
 * @parma {DocInfo} docInfo The page's documentation info object.
 * @param {JSDocInfo} jsdoc The jsdoc for the given node or null if no
 *    doc comments were attached.
 */
FileOverviewV.prototype.visit = function(node, docInfo, jsdoc) {
  var jsdoc = node.getJSDocInfo();

  if (node.getType() === Token.SCRIPT && jsdoc) {
    var fileDesc = docInfo.getFileDescriptor();
    if (jsdoc.hasFileOverview()) {
      this.overviewNode = node;
      var overview = jsdoc.getFileOverview();
    
      // The JSDoc parser does not remove the space after the newline.
      fileDesc.fileOverview = overview.replace(/\n /g, '\n');
    }

    var authors = jsdoc.getAuthors(),
        iter;
    if (authors && authors.size() > 0) {
      var fileAuthors = fileDesc.authors = [];
  
      iter = authors.iterator();
      while (iter.hasNext()) {
        fileAuthors.push(iter.next());
      }
    }

    var references = jsdoc.getReferences();
    if (references && references.size() > 0) {
      var fileRefs = fileDesc.references = [];
      iter = references.iterator();

      while (iter.hasNext()) {
        fileRefs.push(iter.next());
      }
    }
  }

  if (this.nextVisitor_) {
    this.nextVisitor_.visit(node, docInfo, jsdoc);
  }
};
